import os
from io import BytesIO
from builtins import print
import zipfile
import plistlib
import sys
import re
import json

# 创建一个空的plist字典对象
ipa_link_info = {
    "items": [
        {
            "assets": [
                {
                    "kind": "software-package",
                    "url": ""
                },
                {
                    "kind": "display-image",
                    "url": ""
                },
                {
                    "kind": "full-size-image",
                    "url": ""
                }
            ],
            "metadata": {
                "bundle-identifier": "",
                "bundle-version": "",
                "kind": "software",
                "title": ""
            }
        }
    ]
}


def custom_input(describle):
    input_str = input(describle)
    if input_str != 'quit':
        return input_str
    else:
        print("Bye Bye")
        sys.exit(0)


# 获取IPA包中的infoplist
def analyze_ipa_main_plist_with_plistlib(ipa_path):
    if zipfile.is_zipfile(ipa_path):
        ipa_file = zipfile.ZipFile(ipa_path)
        plist_path = find_info_plist_path(ipa_file, 'Info.plist')
        if plist_path is not None:
            info_plist = get_info_plist(ipa_file, plist_path)
            set_matadata(info_plist)
            set_assets()
            write_to_file(info_plist,ipa_path)
        else:
            print('Can not find the info.plist')
    else:
        print('this path has no IPA package!')
        new_ipa_path = custom_input("place input the ipa packet path:")
        analyze_ipa_main_plist_with_plistlib(new_ipa_path)


# 找到ipa包中的info.plist文件
def find_info_plist_path(zip_file, infolist_path):
    name_list = zip_file.namelist()
    pattern = re.compile(r'Payload/[^/]*.app/' + infolist_path)
    for path in name_list:
        m = pattern.match(path)
        if m is not None:
            return m.group()


# 获取info.plist文件
def get_info_plist(ipa_file, plist_path):
    plist_data = ipa_file.read(plist_path)
    plist_root = plistlib.loads(plist_data)
    show_plist_root = input('input "y" to check the info_plist:')
    if show_plist_root == 'y':
        print(json.dumps(plist_root, indent=4, ensure_ascii=False))
    return plist_root


# 设置IPA包信息
def set_matadata(info_plist):
    ipa_link_info['items'][0]['metadata']['bundle-identifier'] = info_plist['CFBundleIdentifier']
    ipa_link_info['items'][0]['metadata']['bundle-version'] = info_plist['CFBundleShortVersionString']
    ipa_link_info['items'][0]['metadata']['title'] = info_plist['CFBundleDisplayName']


# 设置资源地址信息
def set_assets():
    software_package_url = custom_input("input the ipa package url:")
    display_image_url = custom_input("input the display image url:")
    full_size_image_url = custom_input("input the full size image url:")

    ipa_link_info['items'][0]['assets'][0]['url'] = software_package_url
    ipa_link_info['items'][0]['assets'][1]['url'] = display_image_url
    ipa_link_info['items'][0]['assets'][2]['url'] = full_size_image_url


# 打印最终结果
def print_result():
    print(json.dumps(ipa_link_info, indent=4, ensure_ascii=False))  # 缩进4空格，中文字符不转义成Unicode


# 写入到文件中
# info_plist参数是IPA包的info.plist文件，需要其中的数据为输出的plist文件起名
def write_to_file(info_plist,ipa_path):

    show_ipa_link_info = input('input "y" to check the ipa_link_info:')
    if show_ipa_link_info == 'y':
        print(json.dumps(ipa_link_info, indent=4, ensure_ascii=False))

    info_plist_name = info_plist['CFBundleExecutable'] + '_' + info_plist['CFBundleShortVersionString'] + '.plist'

    # new_info_plist = open(os.getcwd() + '/' + info_plist_name, 'w')
    # fp = BytesIO()
    # plistlib.dump(ipa_link_info, fp)
    # new_info_plist.write((fp.getvalue()).decode('utf-8'))
    # new_info_plist.close()
    # print('ipa_link_info has been stored in:', os.getcwd() + '/' + info_plist_name)

    super_path = ipa_path[:ipa_path.rfind('/')]
    new_info_plist2 = open(super_path + '/' + info_plist_name, 'w')
    fp2 = BytesIO()
    plistlib.dump(ipa_link_info, fp2)
    new_info_plist2.write((fp2.getvalue()).decode('utf-8'))
    new_info_plist2.close()
    print('ipa_link_info has been stored in:', super_path + '/' + info_plist_name)


# 开始：获取IPA包的路径
print('input "quit" to exit the program！')
ipa_path = custom_input("place input the ipa packet path:")
# 开始分析IPA包中的info.plist,并取到数据生成需要的plist文件
analyze_ipa_main_plist_with_plistlib(ipa_path)
